import json
from django.conf import settings
from django.core.paginator import InvalidPage, Paginator
from django.http import JsonResponse
from haystack.forms import  ModelSearchForm
from haystack.query import EmptySearchQuerySet

from LaboratoryBuilding.settings import REDIS_HOST, REDIS_PORT
from apis.user.graph_code import GraphCode
RESULTS_PER_PAGE = getattr(settings, 'HAYSTACK_SEARCH_RESULTS_PER_PAGE', 20)
from django.http import HttpResponse
from rest_framework.response import Response
from rest_framework.views import APIView
from apis.celery_pro.tasks import send_phone
from .models import User, Area
from django.contrib.auth.hashers import check_password, make_password
from .serializers import UserSer, AreaSer
from .jwt_app import create_jwt, verify_jwt
from .phone_code import phone_code
from .unique_test import unique
from .user_control import RegUser,LoginUser,Active_User,put_user,update_pwd,verification_phone,phone_update_pwd
import redis
from django.utils.decorators import method_decorator
# 建立连接
r = redis.Redis(host=REDIS_HOST, port=REDIS_PORT)

# 用户名的唯一性验证接口
class Name_Unique(APIView):
    def get(self,request):
        '''
        :param request: 获取前端的参数 用户名或者phone 或者email
        :return: 返回验证状态
        '''
        username = request.data.get("username")
        phone = request.data.get("phone")
        email = request.data.get("email")
        #调用接口
        res = unique(username,phone,email)
        return Response(res)

# 图片验证码
def getVerificationCode(request):
   return GraphCode()

# 注册代码
class Reg(APIView):
    def post(self, request):
        '''
        :param request:需要用户名，密码，手机号，验证码，参数
        :return:  返回注册的成功失败信息
        '''
        username = request.data.get("username")
        password = request.data.get("password")
        phone = request.data.get('phone')
        code = request.data.get("code")
        return RegUser(code,phone,username,password)

class LoginView(APIView):
    def post(self, request):
        '''
        :param request:接收参数用户名，密码
        :return: 返回token
        '''
        username = request.data.get("username")
        password = request.data.get("password")
        return LoginUser(username,password)

# 验证按钮激活账户
def active_user(request):
    '''
    :param request:# 激活用户   获取 连接中带的flag
    :return: 返回用户激活的成功与否
    '''
    flag = request.GET.get("flag")
    return Active_User(flag)


# 手机号时区
class AreaView(APIView):
    def get(self, request):
        ''':return 返回时区表的所有信息
        '''
        queryset = Area.objects.filter(status=1)
        ser = AreaSer(queryset, many=True)
        return Response({"error_code": 200, "message": "获取数据成功", "data": ser.data})

#权限验证装饰器
def my_decorator(func):
    def wrapper(request,*args,**kwargs):
        uid = verify_jwt(request.META.get("HTTP_TOKEN"))
        if not uid:
            return Response({"error_code": 404, "message": "token已失效"})
        return func(request,*args,**kwargs)
    return wrapper

# 个人信息的获取
class Personal(APIView):
    @method_decorator(my_decorator)
    def get(self, request):
        '''
        :param request: 首先要接收参数 token 解析出uid
        :return: 返回个人的不关键信息
        '''
        # 调用接口解析jwt  获取uid信息
        uid = verify_jwt(request.META.get("HTTP_TOKEN"))
        # if not uid:
        #     return Response({"error_code": 404, "message": "token已失效"})
        queryparams = User.objects.get(id=uid, status=1)
        ser = UserSer(queryparams)
        return Response({"error_code": 200, "message": "信息已传递给前端，请接收", "data": ser.data})

    def put(self, request):
        '''
        :param request: 获取token ，获取修改后的信息
        :return:  修改的成功与否 或者是token失效
        '''
        # 获取headers的token信息
        uid = verify_jwt(request.META.get("HTTP_TOKEN"))
        data = request.data
        return put_user(uid,data)


# 登录后修改密码
class Updata_pwd(APIView):
    def put(self, request):
        '''
        :param request: token参数，原密码，新密码
        :return: 返回修改完成后，前端直接把原token删除
        '''
        password = make_password(request.data.get("password"))
        password2 = request.data.get("password2")
        uid = verify_jwt(request.META.get("HTTP_TOKEN"))
        return update_pwd(uid,password,password2)

# 第三方解绑   获取uid后改变第三方map表的状态为0



# 手机验证码发送
# 通过手机号验证手机号，验证码是否匹配
class Phone_pwd(APIView):
    def post(self, request):
        '''
        :param request: 手机号以及手机验证码
        :return: 手机验证码的校验
        '''
        phone = request.data.get('phone')
        code = request.data.get("phone_code")
        return verification_phone(phone,code)

    def put(self, request):
        '''
        :param request: 获取token，新密码
        :return:
        '''
        token = request.META.get("HTTP_TOKEN")
        pwd = request.data.get("password")
        uid = verify_jwt(token)
        return phone_update_pwd(pwd,uid)

    def get(self, request):
        '''
        :param request: 获取手机号
        :return: 返回手机号发送成功是否
        '''
        phone = request.GET.get("phone")
        # uid = verify_jwt(request.META.get("HTTP_TOKEN"))
        # print(phone, uid)
        # if not uid:
        #     return HttpResponse({"error_code": 400, "message": "token已失效"})
        # 判断手机号和数据库手机号是否相符，相符的话发送验证码   未写
        code1 = int(phone_code())
        # 存进redis    #phone作为唯一键
        r.set(phone, code1, ex=120)
        # 异步发送手机号
        try:
            res = send_phone.delay(code1, phone)
            print(res)
            return Response({"error_code": 200, "message": "手机号发送成功"})
        except Exception as e:
            print(e)
            return Response({"error_code": 404, "message": "手机号发送失败"})


#全文检索的案例
def basic_search(request, load_all=True, form_class=ModelSearchForm, searchqueryset=None, extra_context=None, results_per_page=None):
    query = ''
    results = EmptySearchQuerySet()
    if request.GET.get('q'):
        form = form_class(request.GET, searchqueryset=searchqueryset, load_all=load_all)

        if form.is_valid():
            query = form.cleaned_data['q']
            results = form.search()
    else:
        form = form_class(searchqueryset=searchqueryset, load_all=load_all)

    paginator = Paginator(results, results_per_page or RESULTS_PER_PAGE)
    try:
        page = paginator.page(int(request.GET.get('page', 1)))
    except InvalidPage:
        result = {"code": 404, "msg": 'No file found！', "data": []}
        return HttpResponse(json.dumps(result), content_type="application/json")

    context = {
        'form': form,
        'page': page,
        'paginator': paginator,
        'query': query,
        'suggestion': None,
    }
    if results.query.backend.include_spelling:
        context['suggestion'] = form.get_suggestion()

    if extra_context:
        context.update(extra_context)

    jsondata = []
    print(len(page.object_list))
    for result in page.object_list:
        data = {
            'pk': result.object.pk,
            'nickname': result.object.nickname,
            'address': result.object.address,
        }
        jsondata.append(data)
    result = {"code": 200, "msg": 'Search successfully！', "data": jsondata}
    return JsonResponse(result, content_type="application/json")

